#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <memory>
#include "InetAddr.hpp"
#include "Log.hpp"
#include "Connection.hpp"
#include "Sock.hpp"
#include "Epoller.hpp"
#include "IOService.hpp"
#include "Reactor.hpp"
#include "Protocol.hpp"
#include "Calculator.hpp"


using namespace Log_Module;
using namespace std;
using namespace Sock_M;

// 进行连接管理
class Listener : public Connection
{
public:
    Listener(int port)
        : _port(port),
          _listensock(make_unique<Tcp_Socket>())
    {
        _listensock->BulidTcpSock(_port);
        SetSockfd(_listensock->Fd());
        SetEvents(EPOLLIN | EPOLLET);
    }
    virtual void Sender() override {}
    virtual void Recver() override
    {
        while (true)
        {
            InetAddr peer;
            int aerrno = 0;
            int sockfd = _listensock->Accept(&peer, &aerrno);
            if (sockfd > 0)
            {
                LOG(Log_Level::DEBUG) << "Accept success:" << sockfd;
                auto conn = make_shared<IOService>(sockfd);
                conn->Register_Message(HandlerRequest);
                GetOwner()->Insert_Connection(conn);
            }
            else
            {
                if (aerrno == EAGAIN || aerrno == EWOULDBLOCK)
                {
                    LOG(Log_Level::DEBUG) << "accetper all connection ... done";
                    break;
                }
                else if (aerrno == EINTR)
                {
                    LOG(Log_Level::DEBUG) << "accetper intr by signal, continue";
                    continue;
                }
                else
                {
                    LOG(Log_Level::WARNING) << "accetper error ... Ignore";
                    break;
                }
            }
        }
    }
    virtual void Excepter() override
    {
    }
    int Sockfd() { return _listensock->Fd(); }
    ~Listener()
    {
        _listensock->close();
    }

private:
    unique_ptr<Socket> _listensock;
    int _port;
};
